package com.linkai.泛型;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 泛型的特性：只在编译阶段有效
 * @Author: 林凯
 * @Date: 2021/10/21 22:35
 */
public class Test03 {
    public static void main(String[] args) {

        /*
            （1）
            下面的代码，在运行是才会报错，因为List里面类型不一致，后序进行操作时类型转换报错。
            利用泛型可以帮我们解决这一的问题:
                泛型提供了编译时类型安全检测机制，该机制允许程序员在编译时检测到非法的类型。
        * */
//        List list = new ArrayList();
        List<Integer> list = new ArrayList();
//        list.add("abc");      // 使用泛型的话，这句代码在编译时就会报错
        list.add(-1);
        for (Object integer : list) {
            if ((Integer)integer < 0) {
                System.out.println("小与0");
            }
        }

        /*
            （2）泛型只在编译阶段才有效
            在编译之后程序会采取去泛型化的措施。也就是说Java中的泛型，只在编译阶段有效。
            在编译过程中，正确检验泛型结果后，会将泛型的相关信息擦出，并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。
            也就是说，泛型信息不会进入到运行时阶段。

            泛型类型在逻辑上看以看成是多个不同的类型，实际上都是相同的基本类型。
        * */
        List<String> stringList = new ArrayList<>();
        List<Integer> integerList = new ArrayList<>();
        /*
            这里的 ？ 是类型通配符；
            类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?> 在逻辑上是 List<String>,List<Integer> 等所有 List<具体类型实参> 的父类。
            <? extends T>表示该通配符所代表的类型是T类型的子类。
            <? super T>表示该通配符所代表的类型是T类型的父类。
        * */
        Class<? extends List> stringListClass = stringList.getClass();
        Class<? extends List> integerListClass = integerList.getClass();

        if (stringListClass.hashCode() == integerListClass.hashCode()) {
            System.out.println("相同");
        }


    }
}
